using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
/// <summary>
/// 存档系统
/// </summary>
public static class SaveDataSystem
{
    private static string key = "b244a02444908deb248a0792ad540d25";
    /// <summary>
    /// 保存数据
    /// </summary>
    /// <param name="saveFileName">文件名,保存数据的文件名</param>
    /// <param name="data">需要保存的数据</param>
    public static void SaveByJson(string saveFileName, object data)
    {
        var json = JsonUtility.ToJson(data);
        var encryptedJson = EncryptString(key, json);  // AES加密
        var path = Path.Combine(Application.persistentDataPath, saveFileName);

        try
        {
            File.WriteAllText(path, encryptedJson);
            // File.WriteAllText(path, json);
            #if UNITY_EDITOR
            Debug.Log($"成功保存到 {path}.");
            #endif
        }
        catch(System.Exception exception)
        {
            #if UNITY_EDITOR
            Debug.Log($"文件保存到 {path}. \n{exception}");
            #endif
        }
    }
 
    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="saveFileName">读取数据的文件名</param>
    /// <typeparam name="T">泛型</typeparam>
    /// <returns></returns>
    public static T LoadFromJson<T>(string saveFileName)
    {
        var path = Path.Combine(Application.persistentDataPath, saveFileName);
        Debug.Log($"尝试从文件路径加载: {path}");
        try
        {
            // var json = File.ReadAllText(path);
            var encryptedJson = File.ReadAllText(path);
            var json = DecryptString(key, encryptedJson);// 使用解密函数解密数据
            var data = JsonUtility.FromJson<T>(json);
            Debug.Log($"成功读取到 {path}.");
 
            return data;
        }
        catch(System.Exception exception)
        {
            #if UNITY_EDITOR
            Debug.Log($"文件从 {path} 加载. \n{exception}");
            #endif
 
            return default;
        }
    }
 
    /// <summary>
    /// 删除存档
    /// </summary>
    /// <param name="saveFileName"></param>
    public static void DeleteSaveFile(string saveFileName)
    {
        var path = Path.Combine(Application.persistentDataPath, saveFileName);
 
        try
        {
            File.Delete(path);
            Debug.Log($"成功删除到 {path}.");
 
        }
        catch(System.Exception exception)
        {
            #if UNITY_EDITOR
            Debug.Log($"文件从 {path} 删除. \n{exception}");
            #endif
 
        }
    }
    /// <summary>
    /// AES加密函数
    /// </summary>
    /// <param name="key"></param>
    /// <param name="plainText"></param>
    /// <returns></returns>
    public static string EncryptString(string key, string plainText)
    {
        byte[] iv = new byte[16];
        byte[] array;
 
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key);
            aes.IV = iv;
 
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
 
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }
                    array = memoryStream.ToArray();
                }
            }
        }
 
        return Convert.ToBase64String(array);
    }
 
    /// <summary>
    /// AES解密函数
    /// </summary>
    /// <param name="key"></param>
    /// <param name="cipherText"></param>
    /// <returns></returns>
    public static string DecryptString(string key, string cipherText)
    {
        byte[] iv = new byte[16];
        byte[] buffer = Convert.FromBase64String(cipherText);
 
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key);
            aes.IV = iv;
 
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
 
            using (MemoryStream memoryStream = new MemoryStream(buffer))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader streamReader = new StreamReader(cryptoStream))
                    {
                        return streamReader.ReadToEnd();
                    }
                }
            }
        }
    }
 
}   